/*
 * structs.h
 *
 * Dit bestand bevat de datatypen die gebruikt worden voor het werken
 * met B-encoded informatie. Het is niet nodig om deze header in te laden
 * omdat ze al gebruikt wordt door bencode.h en modify_structs.h.
 */

#ifndef STRUCTS_H_
#define STRUCTS_H_

/*
 * Definieer de structs die later worden gebruikt.
 */
struct entry_type;
struct dictionary_type;
struct list_type;
struct dict_entry_type;
struct list_entry_type;

/*
 * Maak een tal van referentietypes.
 */
typedef struct entry_type      *entry_ptr;
typedef struct dictionary_type *dictionary_ptr;
typedef struct list_type       *list_ptr;
typedef struct dict_entry_type *dict_entry_ptr;
typedef struct list_entry_type *list_entry_ptr;
typedef char*                  *string_ptr;
typedef int                    *integer_ptr;



/*
 * entry_t
 * Dit is de algemene container voor een primitief type.
 * Bevat een type in het attribuut 'type' en een pointer naar de gekoppelde data in 'data'.
 * Gebruik dus voor '.type == TYPE_LIST' het attribuut '.data.list'.
 */
typedef struct entry_type {
	enum type_enum {
		TYPE_DICTIONARY,
		TYPE_LIST,
		TYPE_STRING,
		TYPE_INTEGER
	} type;
	union data_union {
		dictionary_ptr dictionary;
		list_ptr list;
		string_ptr string;
		integer_ptr integer;
	} data;
} entry_t;

/*
 * string_t
 * Dit is een van de 4 primitieve types, namelijk een tekst.
 * Geïmplementeerd als char*.
 */
typedef char *string_t;

/*
 * integer_t
 * Dit is een van de 4 primitieve types, namelijk een getal.
 */
typedef int integer_t;

/*
 * dict_entry_t
 * Dit is een element uit een linked-list die een verzameling key-value-paren bevat.
 * De key zit in het attribuut 'name' en bevat een tekst-pointer.
 * De value zit in het attribuut 'value' en bevat een entry_t-pointer.
 * Een dictionary_t bestaat uit een referentie naar één dict_entry_t en een
 * dict_entry_t bevat vervolgens een referentie naar een ander element via het attribuut 'next'
 */
typedef struct dict_entry_type {
	string_t name;
	entry_ptr value;
	dict_entry_ptr next;
} dict_entry_t;

/*
 * list_entry_t
 * Dit is een element uit een linked-list die een array van entry_t's bevat.
 * Een list_t bestaat uit een referentie naar één list_entry_t en een list_entry_t
 * bevat vervolgens een referentie naar een ander element via het attribuut 'next'
 */
typedef struct list_entry_type {
	entry_ptr value;
	list_entry_ptr next;
} list_entry_t;

/*
 * dictionary_t
 * Dit is een van de 4 primitieve types, namelijk de dictionary of map.
 * Het bevat een lijst ( [0,oneindig> elementen) met key-value-paren.
 */
typedef struct dictionary_type {
	dict_entry_ptr first, last;
} dictionary_t;

/*
 * list_t
 * Dit is een van de 4 primitieve types, namelijk de array.
 * Het bevat een lijst met [0,oneindig> entry_t's.
 */
typedef struct list_type {
	list_entry_ptr first, last;

} list_t;

#endif /* STRUCTS_H_ */
